Verifieer telefoonnummers op internet met de WebOTP API

Help gebruikers met OTP's die ze via sms hebben ontvangen

Wat is de WebOTP API?

Tegenwoordig bezit de meeste mensen ter wereld een mobiel apparaat en gebruiken ontwikkelaars telefoonnummers steeds vaker als identificatiemiddel voor gebruikers van hun diensten.

Er zijn verschillende manieren om telefoonnummers te verifiëren, maar een willekeurig gegenereerd eenmalig wachtwoord (OTP) dat per sms wordt verzonden, is een van de meest voorkomende. Het terugsturen van deze code naar de server van de ontwikkelaar toont aan dat u controle heeft over het telefoonnummer.

Dit idee wordt al in veel scenario's toegepast om het volgende te bereiken:

  • Telefoonnummer als identificatie voor de gebruiker. Bij aanmelding voor een nieuwe dienst vragen sommige websites om een ​​telefoonnummer in plaats van een e-mailadres en gebruiken dit als accountidentificatie.
  • Tweestapsverificatie. Bij het inloggen vraagt ​​een website om een ​​eenmalige code die via sms wordt verzonden, naast een wachtwoord of andere kennisfactor voor extra beveiliging.
  • Betalingsbevestiging. Wanneer een gebruiker een betaling doet, kan het vragen om een ​​eenmalige code via sms helpen om de intentie van de persoon te verifiëren.

Het huidige proces zorgt voor problemen bij gebruikers. Het vinden van een eenmalig wachtwoord (OTP) in een sms-bericht en het vervolgens kopiëren en plakken naar het formulier is omslachtig, wat de conversiepercentages in kritieke gebruikerservaringen verlaagt. Het vereenvoudigen hiervan is een al lang bestaande wens van veel van de grootste wereldwijde ontwikkelaars voor het web. Android heeft een API die precies dit doet . Dat geldt ook voor iOS en Safari .

Met de WebOTP API kan je app speciaal geformatteerde berichten ontvangen die aan je app-domein zijn gekoppeld. Zo kun je programmatisch een eenmalig wachtwoord (OTP) uit een sms-bericht halen en gemakkelijker een telefoonnummer van de gebruiker verifiëren.

Zie het in actie

Stel dat een gebruiker zijn telefoonnummer wil verifiëren via een website. De website stuurt de gebruiker een sms-bericht en de gebruiker voert de eenmalig wachtwoord (OTP) uit het bericht in om de eigenaar van het telefoonnummer te verifiëren.

Met de WebOTP API zijn deze stappen voor de gebruiker slechts één tik, zoals te zien is in de video. Wanneer het sms-bericht binnenkomt, verschijnt er een venster waarin de gebruiker wordt gevraagd zijn of haar telefoonnummer te verifiëren. Nadat de gebruiker op de knop Verifiëren op het venster heeft geklikt, plakt de browser het eenmalige wachtwoord in het formulier en wordt het formulier verzonden zonder dat de gebruiker op Doorgaan hoeft te klikken.

Het hele proces wordt schematisch weergegeven in de afbeelding hieronder.

WebOTP API-diagram

Probeer de demo zelf. Er wordt niet om je telefoonnummer gevraagd en er wordt geen sms naar je apparaat verzonden. Je kunt er wel een vanaf een ander apparaat verzenden door de tekst in de demo te kopiëren. Dit werkt omdat het bij gebruik van de WebOTP API niet uitmaakt wie de afzender is.

  1. Ga naar https://web-otp.glitch.me in Chrome 84 of later op een Android-apparaat.
  2. Stuur het volgende sms-bericht vanaf een andere telefoon naar je telefoon.
Your OTP is: 123456.

@web-otp.glitch.me #123456

Heb je de sms ontvangen en de prompt gezien om de code in te voeren in het invoerveld? Zo werkt de WebOTP API voor gebruikers.

Het gebruik van de WebOTP API bestaat uit drie delen:

  • Een correct geannoteerde <input> -tag
  • JavaScript in uw web-app
  • Geformatteerde berichttekst verzonden via SMS.

Ik zal eerst de <input> tag bespreken.

Een <input> -tag annoteren

WebOTP zelf werkt zonder HTML-annotatie, maar voor compatibiliteit met meerdere browsers raad ik u ten zeerste aan om autocomplete="one-time-code" toe te voegen aan de <input> -tag op de plek waar u verwacht dat de gebruiker een OTP invoert.

Hierdoor kan Safari 14 of later voorstellen dat de gebruiker het veld <input> automatisch invult met een eenmalig wachtwoord wanneer deze een sms-bericht ontvangt met de indeling die wordt beschreven in Sms-bericht opmaken, ook al ondersteunt Safari geen WebOTP.

HTML

<form>
  <input autocomplete="one-time-code" required/>
  <input type="submit">
</form>

Gebruik de WebOTP API

Omdat WebOTP eenvoudig is, is het kopiëren en plakken van de volgende code voldoende. Ik leg je in ieder geval uit wat er gebeurt.

JavaScript

if ('OTPCredential' in window) {
  window.addEventListener('DOMContentLoaded', e => {
    const input = document.querySelector('input[autocomplete="one-time-code"]');
    if (!input) return;
    const ac = new AbortController();
    const form = input.closest('form');
    if (form) {
      form.addEventListener('submit', e => {
        ac.abort();
      });
    }
    navigator.credentials.get({
      otp: { transport:['sms'] },
      signal: ac.signal
    }).then(otp => {
      input.value = otp.code;
      if (form) form.submit();
    }).catch(err => {
      console.log(err);
    });
  });
}

Functiedetectie

Featuredetectie is hetzelfde als voor veel andere API's. Door te luisteren naar DOMContentLoaded -gebeurtenis wordt gewacht tot de DOM-boom klaar is voor query's.

JavaScript

if ('OTPCredential' in window) {
  window.addEventListener('DOMContentLoaded', e => {
    const input = document.querySelector('input[autocomplete="one-time-code"]');
    if (!input) return;
    
    const form = input.closest('form');
    
  });
}

Verwerk de OTP

De WebOTP API zelf is eenvoudig genoeg. Gebruik navigator.credentials.get() om de OTP te verkrijgen. WebOTP voegt een nieuwe otp optie toe aan die methode. Deze heeft slechts één eigenschap: transport , waarvan de waarde een array moet zijn met de string 'sms' .

JavaScript

    …
    navigator.credentials.get({
      otp: { transport:['sms'] }
      …
    }).then(otp => {
    …

Dit activeert de toestemmingsstroom van de browser wanneer een sms-bericht binnenkomt. Als de toestemming wordt verleend, wordt de geretourneerde belofte omgezet in een OTPCredential -object.

Inhoud van het verkregen OTPCredential object

{
  code: "123456" // Obtained OTP
  type: "otp"  // `type` is always "otp"
}

Geef vervolgens de OTP-waarde door aan het veld <input> . Door het formulier direct te versturen, hoeft de gebruiker niet op een knop te tikken.

JavaScript

    
    navigator.credentials.get({
      otp: { transport:['sms'] }
      
    }).then(otp => {
      input.value = otp.code;
      if (form) form.submit();
    }).catch(err => {
      console.error(err);
    });
    

Het bericht afbreken

Als de gebruiker handmatig een OTP invoert en het formulier verzendt, kunt u de get() aanroep annuleren door een AbortController instantie te gebruiken in het options -object .

JavaScript

    
    const ac = new AbortController();
    
    if (form) {
      form.addEventListener('submit', e => {
        ac.abort();
      });
    }
    
    navigator.credentials.get({
      otp: { transport:['sms'] },
      signal: ac.signal
    }).then(otp => {
    

Het sms-bericht opmaken

De API zelf ziet er eenvoudig uit, maar er zijn een paar dingen die u moet weten voordat u deze gebruikt. Het bericht moet worden verzonden nadat navigator.credentials.get() is aangeroepen en moet worden ontvangen op het apparaat waarop get() is aangeroepen. Ten slotte moet het bericht voldoen aan de volgende opmaak:

  • Het bericht begint met voor mensen leesbare tekst die bestaat uit een alfanumerieke tekenreeks van vier tot tien tekens, met minstens één cijfer op de laatste regel voor de URL en de OTP.
  • Het domeingedeelte van de URL van de website die de API aanroept, moet worden voorafgegaan door @ .
  • De URL moet een hekje (' # ') bevatten, gevolgd door de OTP.

Bijvoorbeeld:

Your OTP is: 123456.

@www.example.com #123456

Hier zijn enkele slechte voorbeelden:

Voorbeeld van een misvormde sms-tekst Waarom dit niet zal werken
Here is your code for @example.com #123456 @ moet het eerste teken van de laatste regel zijn.
Your code for @example.com is #123456 @ moet het eerste teken van de laatste regel zijn.
Your verification code is 123456

@example.com\t#123456
Er wordt één spatie verwacht tussen @host en #code .
Your verification code is 123456

@example.com    #123456
Er wordt één spatie verwacht tussen @host en #code .
Your verification code is 123456

@ftp://example.com #123456
URL-schema kan niet worden opgenomen.
Your verification code is 123456

@https://example.com #123456
URL-schema kan niet worden opgenomen.
Your verification code is 123456

@example.com:8080 #123456
Poort kan niet worden opgenomen.
Your verification code is 123456

@example.com/foobar #123456
Pad kan niet worden opgenomen.
Your verification code is 123456

@example .com #123456
Geen spaties in domein.
Your verification code is 123456

@domain-forbiden-chars-#%/:<>?@[] #123456
Geen verboden tekens in het domein.
@example.com #123456

Mambo Jumbo
@host en #code moeten de laatste regel zijn.
@example.com #123456

App hash #oudf08lkjsdf834
@host en #code moeten de laatste regel zijn.
Your verification code is 123456

@example.com 123456
# ontbreekt.
Your verification code is 123456

example.com #123456
@ ontbreekt.
Hi mom, did you receive my last text @ en # ontbreken.

Demo's

Probeer verschillende berichten met de demo: https://web-otp.glitch.me

Je kunt het ook forken en je eigen versie maken: https://glitch.com/edit/#!/web-otp .

WebOTP gebruiken vanuit een cross-origin iframe

Het invoeren van een SMS-OTP in een cross-origin iframe wordt meestal gebruikt voor betalingsbevestiging, vooral met 3D Secure. De WebOTP API biedt een gemeenschappelijk formaat voor cross-origin iframes en levert OTP's die gekoppeld zijn aan geneste oorsprongen. Bijvoorbeeld:

  • Een gebruiker bezoekt shop.example om een ​​paar schoenen te kopen met een creditcard.
  • Nadat het creditcardnummer is ingevoerd, toont de geïntegreerde betalingsaanbieder een formulier van bank.example in een iframe, waarin de gebruiker wordt gevraagd zijn telefoonnummer te verifiëren om snel te kunnen afrekenen.
  • bank.example verstuurt een sms-bericht met daarin een eenmalig wachtwoord (OTP) naar de gebruiker, zodat deze deze kan invoeren om zijn identiteit te verifiëren.

Om de WebOTP API vanuit een cross-origin iframe te gebruiken, moet u twee dingen doen:

  • Geef zowel de oorsprong van het bovenste frame als de oorsprong van het iframe aan in het sms-bericht.
  • Configureer het machtigingsbeleid zodat de cross-origin iframe rechtstreeks een OTP van de gebruiker kan ontvangen.
WebOTP API binnen een iframe in actie.

U kunt de demo proberen op https://web-otp-iframe-demo.stackblitz.io .

Annoteer gebonden oorsprongen aan het sms-bericht

Wanneer de WebOTP API vanuit een iframe wordt aangeroepen, moet het sms-bericht de oorsprong van het bovenste frame bevatten, voorafgegaan door @ gevolgd door de OTP voorafgegaan door # en de oorsprong van het iframe voorafgegaan door @ op de laatste regel.

Your verification code is 123456

@shop.example #123456 @bank.exmple

Machtigingsbeleid configureren

Om WebOTP in een cross-origin iframe te gebruiken, moet de embedder toegang tot deze API verlenen via het otp-credentials -machtigingsbeleid om onbedoeld gedrag te voorkomen. Over het algemeen zijn er twee manieren om dit doel te bereiken:

via HTTP-header:

Permissions-Policy: otp-credentials=(self "https://bank.example")

via iframe allow attribuut:

<iframe src="https://bank.example/…" allow="otp-credentials"></iframe>

Bekijk meer voorbeelden over hoe u een machtigingsbeleid kunt specificeren .

WebOTP gebruiken op desktop

In Chrome ondersteunt WebOTP het luisteren naar sms-berichten die op andere apparaten worden ontvangen, zodat gebruikers hun telefoonnummer op hun desktop kunnen verifiëren.

WebOTP API op desktop.

Voor deze mogelijkheid moet de gebruiker zich met hetzelfde Google-account aanmelden op zowel Chrome op desktop als Chrome in Android.

Het enige wat ontwikkelaars hoeven te doen, is de WebOTP API op hun desktopwebsite implementeren, net zoals ze dat op hun mobiele website doen. Er zijn geen speciale trucs voor nodig.

Meer informatie vindt u in Verifieer een telefoonnummer op uw desktop met behulp van de WebOTP API .

Veelgestelde vragen

Het dialoogvenster verschijnt niet, hoewel ik een correct geformatteerd bericht verstuur. Wat gaat er mis?

Er zijn een paar kanttekeningen bij het testen van de API:

  • Als het telefoonnummer van de afzender is opgenomen in de contactenlijst van de ontvanger, wordt deze API niet geactiveerd vanwege het ontwerp van de onderliggende SMS User Consent API .
  • Als u een werkprofiel op uw Android-apparaat gebruikt en WebOTP niet werkt, probeer dan Chrome te installeren en te gebruiken op uw persoonlijke profiel (dat wil zeggen, hetzelfde profiel waarin u sms-berichten ontvangt).

Controleer de opmaak om te zien of uw sms-bericht correct is opgemaakt.

Is deze API compatibel met verschillende browsers?

Chromium en WebKit zijn het eens geworden over het sms-formaat en Apple heeft aangekondigd dat Safari dit vanaf iOS 14 en macOS Big Sur gaat ondersteunen . Hoewel Safari de WebOTP JavaScript API niet ondersteunt, stelt het standaardtoetsenbord automatisch voor om de eenmalige wachtwoordinvoer in te voeren als het sms-bericht aan het formaat voldoet, door een input te annoteren met autocomplete=["one-time-code"] .

Is het veilig om SMS te gebruiken als authenticatiemiddel?

Hoewel SMS OTP handig is om een ​​telefoonnummer te verifiëren wanneer het voor het eerst wordt verstrekt, moet telefoonnummerverificatie via sms voorzichtig worden gebruikt voor herauthenticatie, aangezien telefoonnummers door providers kunnen worden gekaapt en hergebruikt. WebOTP is een handig mechanisme voor herauthenticatie en -herstel, maar services zouden dit moeten combineren met aanvullende factoren, zoals een kennisvraag, of de Web Authentication API moeten gebruiken voor sterke authenticatie.

Waar kan ik bugs in de implementatie van Chrome melden?

Heb je een bug gevonden in de implementatie van Chrome?

  • Meld een bug op crbug.com . Geef zoveel mogelijk details, eenvoudige instructies voor reproductie en stel Componenten in op Blink>WebOTP .

Hoe kan ik deze functie verbeteren?

Bent u van plan de WebOTP API te gebruiken? Uw publieke steun helpt ons bij het prioriteren van functies en laat andere browserleveranciers zien hoe belangrijk het is om deze te ondersteunen. Stuur een tweet naar @ChromiumDev met de hashtag #WebOTP en laat ons weten waar en hoe u de API gebruikt.

Bronnen